home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir34
/
xpcbpath.zip
/
XPCBPATH.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-06-04
|
8KB
|
405 lines
/* -----------------------------------------------------------------------
XPCBPATH Version 1.0, June 4, 1994.
(c) 1994 Key Software Products.
All Rights Reserved.
This software is copyrighted. You are free to use it as you
like, except:
(1) If modified, you must keep the copyright notice in the
source and executable code, and this comment in the source.
(2) It may not be incorporated into a commercial product without
the author's permission.
-----------------------------------------------------------------------
This software has been compiled with the DeSmet C88 compiler and linker.
----------------------------------------------------------------------- */
#include <stdio.h>
#define PGM_NAME "XPCBPATH"
#define VERSION "1.0"
#define MAX_ENTRIES 100
#define STACK_SIZE 512
#define PCBSIZE 31
#define DOSSIZE 65
#define ENDOF(bfr) &bfr[strlen(bfr)]
typedef struct PATH
{
char old[PCBSIZE] ;
char new[DOSSIZE] ;
} PATH ;
char path[DOSSIZE] ;
char rest[DOSSIZE] ;
unsigned entries = 0 ;
PATH subst[MAX_ENTRIES] ;
/* These functions must be in the resident portion of the code segment */
/* If we use the ones in the library, they'll be tacked on to the end */
/* of this code, and then discarded when we go TSR! */
#define strlen _strlen
#define strcpy _strcpy
#define strncat _strncat
#define toupper _toupper
#define strncmpi _strncmpi
void Sign_On(void) ;
unsigned showcs(void) ;
unsigned showds(void) ;
void lmove(unsigned, unsigned, unsigned, unsigned, unsigned) ;
int strlen(char *) ;
void strcpy(char *, char *) ;
void strncat(char *, char *, int) ;
char toupper(char) ;
int strncmpi(char *, char *, int) ;
char *Fix_Path(char *, unsigned) ;
void TSR(unsigned, unsigned) ;
void CS_End(void) ;
unsigned Substitute(int, char *[]) ;
void Announce(unsigned, char *, char *) ;
void Usage(char *) ;
void Int21()
{
#ifndef _lint
#asm
;----------------------------------------------------------
New_Int21:
;----------------------------------------------------------
pushf ; Preserve flags
cmp ah,3Bh ; Set current directory?
je Subst
cmp ah,3Dh ; Open file?
je Subst
cmp ax,4300h ; Get file attributes?
je Subst
cmp ah,4Eh ; Find first?
je Subst
popf ; Restore flags
db 0EAh ; JMP FAR DIRECT
Old_Int21 dw 0 ; offset
dw 0 ; segment
save_ss dw 0
save_sp dw 0
stack_seg dw 0
stack_ptr dw 0
Subst: add sp,2 ; Discard flags saved above
; Important input registers: AX, CX, DS:DX
mov save_ss,ss ; preserve stack
mov save_sp,sp
mov ss,stack_seg ; establish my stack
mov sp,stack_ptr
push bx ; preserve irrelevant registers
push si
push di
push es
push ax ; preserve relevant registers
push cx
push ds ; parameter #2 (segment)
push dx ; parameter #1 (offset)
mov ds,stack_seg ; establish my data segment
call Fix_Path_ ; returns DS:AX => new path
mov dx,ax
pop di ; save original DX in DI
pop si ; save original DS in SI
pop cx ; restore other relevant registers
pop ax
pushf ; Simulate INT 21h
lcall DWORD Old_Int21 ; Don't change CF or AX after here!
mov dx,di ; restore REAL DX
mov ds,si ; restore REAL DS
pop es ; restore irrelevant registers
pop di
pop si
pop bx
mov ss,save_ss
mov sp,save_sp
lret 2
#end
#endif
}
unsigned showds()
{
#ifndef _lint
#asm
mov ax,ds
#end
#endif
}
unsigned showcs()
{
#ifndef _lint
#asm
mov ax,cs
#end
#endif
}
void lmove(bytes, src_off, src_seg, dst_off, dst_seg)
unsigned bytes ;
unsigned src_off ;
unsigned src_seg ;
unsigned dst_off ;
unsigned dst_seg ;
{
#ifndef _lint
#asm
push ds
mov cx,#bytes
les di,#dst_off
lds si,#src_off
cld
rep movsb
pop ds
#end
#endif
}
char *Fix_Path(off, seg)
char *off ;
unsigned seg ;
{
int i, len ;
PATH *p ;
lmove(sizeof(path), off, seg, path, showds()) ;
p = subst ;
for (i = 0; i < entries; i++, p++)
{
len = strlen(p->old) ;
if (strncmpi(path, p->old, len) == 0)
{
strcpy(rest, path + len) ;
strcpy(path, p->new) ;
strncat(path, rest, (DOSSIZE - 1) - strlen(p->new)) ;
break ;
}
}
return path ;
}
int strlen(str)
char *str ;
{
int len ;
len = 0 ;
while (*str++) len++ ;
return len ;
}
void strcpy(dst, src)
char *dst ;
char *src ;
{
while (*src) *dst++ = *src++ ;
*dst = '\0' ;
}
void strncat(dst, src, n)
char *dst ;
char *src ;
int n ;
{
dst += strlen(dst) ;
while (*src && n--) *dst++ = *src++ ;
*dst = '\0' ;
}
char toupper(ch)
char ch ;
{
if ('a' <= ch && ch <= 'z') ch = ch - 'a' + 'A' ;
return ch ;
}
int strncmpi(str1, str2, n)
char *str1 ;
char *str2 ;
int n ;
{
char ch1, ch2 ;
while (*str1 && *str2 && n--)
{
ch1 = toupper(*str1++) ;
ch2 = toupper(*str2++) ;
if (ch1 != ch2) return 1 ;
}
return 0 ;
}
void TSR(stk_ptr, stk_seg)
unsigned stk_ptr ;
unsigned stk_seg ;
{
#ifndef _lint
#asm
mov ax,#stk_ptr
mov WORD stack_ptr,ax
mov ax,#stk_seg
mov stack_seg,ax
xor ax,ax
mov ds,ax
; preserve old int 21h vector
les ax,[4*21h]
mov Old_Int21[0],ax
mov Old_Int21[2],es
; modify int 21h vector
cli
mov WORD [4*21h+0],OFFSET New_Int21
mov WORD [4*21h+2],cs
sti
; terminate but stay resident
mov dx,stack_seg
mov ax,cs
sub dx,ax ; DX = para size of cseg
mov ax,stack_ptr
add ax,256+15 ; PSP plus rounding
mov cl,4
shr ax,cl ; AX = stack paragraphs
add dx,ax
mov ax,3100h
int 21h
#end
#endif
}
void main(argc, argv)
int argc ;
char *argv[] ;
{
unsigned size, dseg ;
Sign_On() ;
entries = Substitute(argc, argv) ;
dseg = showcs() + (((unsigned) CS_End + 15) >> 4) ;
size = subst + entries ;
lmove(size, 0, showds(), 0, dseg) ;
TSR(size + STACK_SIZE, dseg) ;
}
void CS_End() /* Only initialization code below here! */
{
}
unsigned Substitute(argc, argv)
int argc ;
char *argv[] ;
{
unsigned entries = 0 ;
char *p, bfr[100] ;
FILE *fp ;
if (argc != 2) Usage("Wrong number of command line arguments") ;
fp = fopen(argv[1], "r") ;
if (!fp) Usage("Can't find file") ;
puts("") ;
while (fgets(bfr, sizeof(bfr), fp))
{
if (p = strchr(bfr, '\n')) *p = '\0' ;
while (isspace(*bfr)) strcpy(bfr, bfr + 1) ;
if (p = strpbrk(bfr, " \t"))
{
char *old, *new ;
old = bfr ;
*p++ = '\0' ;
while (isspace(*p)) p++ ;
new = p ;
if (p = strpbrk(new, " \t")) *p = '\0' ;
strncpy(subst[entries].old, old, PCBSIZE - 1) ;
strncpy(subst[entries].new, new, DOSSIZE - 1) ;
entries++ ;
Announce(entries, old, new) ;
if (entries >= MAX_ENTRIES) break ;
}
}
fclose(fp) ;
return entries ;
}
void Announce(entry, old, new)
unsigned entry ;
char *old ;
char *new ;
{
char bfr[100] ;
strcpy(bfr, "\t") ;
ltoa((long) entry, ENDOF(bfr), 10) ;
strcat(bfr, ": ") ;
strcat(bfr, old) ;
strcat(bfr, " ==> ") ;
strcat(bfr, new) ;
puts(bfr) ;
}
void Sign_On()
{
char bfr[100] ;
strcpy(bfr, "\n") ;
strcat(bfr, PGM_NAME) ;
strcat(bfr, " v") ;
strcat(bfr, VERSION) ;
strcat(bfr, " (c) 1994 Key Software Products. All Rights Reserved.");
puts(bfr) ;
}
void Usage(msg)
char *msg ;
{
char bfr[100] ;
strcpy(bfr, "\n\tError: ") ;
strcat(bfr, msg) ;
puts(bfr) ;
strcpy(bfr, "\n\tUsage: ") ;
strcat(bfr, PGM_NAME) ;
strcat(bfr, " <filespec>") ;
puts(bfr) ;
exit(255) ;
}